// RegRGS.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

void DisplayMessage(LPCTSTR szMsg, BOOL bConsole)
{
	if (bConsole)
		printf("%s\n", szMsg);
	else
		MessageBox(NULL, szMsg, "REGRGS", MB_OK);
}

int main(int argc, char* argv[])
{
	USES_CONVERSION;
	CRegObject ro;
	LPTSTR szRGS = NULL;
	BOOL bRegister = TRUE, bSilent = FALSE, bConsole = FALSE;
	TCHAR szHelp[] = "Usage is: REGRGS [/?] [/s] [/u] [/c] FILENAME.RGS [Replaceable Parameter=\"Value\"]\n\nArguments in square brackets [ ] are optional.\n/? - Displays this help dialog\n/s - Silent mode.\n/u - Performs unregistration.\n/c - Send output to console.\nReplaceable Parameter - Anything in the RGS file surrounded by % is a replaceable parameter. For example, %MODULE%.\nValue - You must provide a value for replaceable parameters. For example, to register an RGS file that contains %MODULE%:\n\n\tREGRGS.EXE MYOBJECT.RGS MODULE=\"c:\\Program Files\\MyProgram\\myobject.dll\"";
	// display help dialog if no arguments
	if (argc < 2)
	{
		DisplayMessage(szHelp, bConsole);
		exit(1);
	}

	ro.FinalConstruct();

	// process commandline arguments
	for (int iCntr=1; iCntr<argc; iCntr++)
	{
		LPTSTR pTemp = NULL;
		// display help dialog
		if (0 == lstrcmpi(argv[iCntr], _T("/?")))
		{
			DisplayMessage(szHelp, bConsole);
			exit(1);
		}
		// unregister
		else if (0 == lstrcmpi(argv[iCntr], _T("/u")))
			bRegister = FALSE;
		// don't display any messages
		else if (0 == lstrcmpi(argv[iCntr], _T("/s")))
			bSilent = TRUE;
		// send output to console
		else if (0 == lstrcmpi(argv[iCntr], _T("/c")))
			bConsole = TRUE;
		// store RGS file
		else if (strstr(argv[iCntr], ".RGS") || strstr(argv[iCntr], ".rgs"))
			szRGS = argv[iCntr];
		// parse replaceable parameters
		else if (pTemp = strchr(argv[iCntr], '='))
		{
			TCHAR szParam[256], szValue[256];
			ZeroMemory(szParam, 256);
			ZeroMemory(szValue, 256);
			lstrcpyn(szParam, argv[iCntr], pTemp-argv[iCntr]+1);
			pTemp++;
			if ('"' == *pTemp)
				pTemp++;

			LPTSTR pTemp2 = szValue;
			while (*pTemp && *pTemp != '"')
				*pTemp2++ = *pTemp++;

			if (*szParam && *szValue)
				ro.AddReplacement(T2OLE(szParam), T2OLE(szValue));
			else
			{
				DisplayMessage(szHelp, bConsole);
				exit(1);
			}
		}
	}

	// RGS file not specified
	if (NULL == szRGS)
	{
		DisplayMessage(szHelp, bConsole);
		exit(1);
	}

	HRESULT hr;
	// call CRegObject::FileRegister or FileUnregister
	if (bRegister)
		hr = ro.FileRegister(T2OLE(szRGS));
	else
		hr = ro.FileUnregister(T2OLE(szRGS));
	// display error
	if (FAILED(hr))
	{
		LPTSTR szErrMsg = NULL;
		// DISP_E_EXCEPTION is commonly caused by having a replaceable parameter in the RGS and not setting it via the commandline
		if (DISP_E_EXCEPTION == hr)
		{
			TCHAR szException[] = "Exception occurred. Anything in the RGS file that is surrounded by % is a replaceable parameter and you must provide a value for it when running REGRGS.  For example: MODULE=\"c:\\Program Files\\MyProgram\\myobject.dll\"";
			szErrMsg = (LPTSTR)LocalAlloc(0, lstrlen(szException)+1);
			lstrcpy (szErrMsg, szException);
		}
		else
			FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL,
				hr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&szErrMsg, 0, NULL);
		LPTSTR szMsg = new TCHAR[lstrlen(szErrMsg)+60];
		if (bRegister)
			wsprintf(szMsg, "Registration failed.\n\nError #0x%x - %s", hr, szErrMsg);
		else
			wsprintf(szMsg, "Unregistration failed.\nError #0x%x - %s", hr, szErrMsg);
		DisplayMessage(szErrMsg, bConsole);
		delete [] szMsg;
		LocalFree(szErrMsg);
		exit(2);
	}
	// only display success dialog if /s not specified
	else if (!bSilent)
	{
		if (bRegister)
			DisplayMessage("Registration succeeded!", bConsole);
		else
			DisplayMessage("Unregistration succeeded!", bConsole);
	}

	return 0;
}